// 与进程相关的声明与定义
struct spinlock;

// 进程切换上下文，仅保存本进程的上下文
struct context {
    uint64 ra;              // 返回地址
    uint64 sp;              // 栈顶指针

    // callee-saved
    uint64 s0;
    uint64 s1;
    uint64 s2;
    uint64 s3;
    uint64 s4;
    uint64 s5;
    uint64 s6;
    uint64 s7;
    uint64 s8;
    uint64 s9;
    uint64 s10;
    uint64 s11;
};

// 定义每个cpu的状态
struct cpu {
    struct proc *proc;         // 当前cpu上运行的进程
    struct context context;    // 当前cpu上进程的上下文环境
    int intrdep;               // 中断深度，表示嵌套中断调用了多少次
    int intrprev;              // 记录进入嵌套中断之前的中断使能状态
};
extern struct cpu cpus[NCPU];      // 全局数组，记录每个cpu的状态

// 内核态与用户态切换上下文，保存完整的用户态上下文
struct trapframe {
  /*   0 */ uint64 kernel_satp;   // 内核页表
  /*   8 */ uint64 kernel_sp;     // 进程内核栈顶
  /*  16 */ uint64 kernel_trap;   // usertrap()地址
  /*  24 */ uint64 epc;           // 用户程序计数器
  /*  32 */ uint64 kernel_hartid; // hartid
  /*  40 */ uint64 ra;
  /*  48 */ uint64 sp;
  /*  56 */ uint64 gp;
  /*  64 */ uint64 tp;
  /*  72 */ uint64 t0;
  /*  80 */ uint64 t1;
  /*  88 */ uint64 t2;
  /*  96 */ uint64 s0;
  /* 104 */ uint64 s1;
  /* 112 */ uint64 a0;
  /* 120 */ uint64 a1;
  /* 128 */ uint64 a2;
  /* 136 */ uint64 a3;
  /* 144 */ uint64 a4;
  /* 152 */ uint64 a5;
  /* 160 */ uint64 a6;
  /* 168 */ uint64 a7;
  /* 176 */ uint64 s2;
  /* 184 */ uint64 s3;
  /* 192 */ uint64 s4;
  /* 200 */ uint64 s5;
  /* 208 */ uint64 s6;
  /* 216 */ uint64 s7;
  /* 224 */ uint64 s8;
  /* 232 */ uint64 s9;
  /* 240 */ uint64 s10;
  /* 248 */ uint64 s11;
  /* 256 */ uint64 t3;
  /* 264 */ uint64 t4;
  /* 272 */ uint64 t5;
  /* 280 */ uint64 t6;
};
// 进程状态
enum procstate { UNUSED, USED, SLEPPING, RUNNABLE, RUNNING, ZOMBIE };
// 进程控制块
struct proc {
    struct spinlock lock;     // 进程自旋锁，保护进程控制块的并发访问

    int pid;                   // 进程id，用于唯一标识进程
    char name[16];             // 进程名称
    enum procstate state;      // 进程状态
    int killed;                // 进程是否被杀死
    
    struct proc *parent;       // 父进程

    uint64 kstack;             // 内核栈的虚拟地址
    uint64 sz;                 // 进程内存大小
    pagetable_t pagetable;     // 进程页表
    struct trapframe *trapframe; // 进程陷入上下文
    struct context context;    // 进程调度上下文
};